package com.javawork.juc.four;

/**
 * 一个多线程下的单例 DCL + Volatile
 * @author zhangxiaolu
 * @since 2023-02-11 18:14
 */
public class DoubleCheckSingleton {

    //使用volatile解决隐患
    private volatile static DoubleCheckSingleton singleton;

    //私有构造方法
    private DoubleCheckSingleton() {

    }

    //双重锁设计
    public static DoubleCheckSingleton getInstance() {
        if (singleton == null) {
            //多线程并发创建对象时，会通过加锁保证只有一个线程能创造对象
            synchronized (DoubleCheckSingleton.class) {
                if (singleton == null) {
                    //隐患：多线程环境下，由于重排序，该对象可能还未完成初始化就被其他线程读取
                    //解决隐患原理：利用volatile，禁止”初始化对象”（2）和”设置singleton费向内存空间"（3）的重排序
                    singleton = new DoubleCheckSingleton();
                }
            }
        }
        //对象创建完毕，执行getInstance()将不需要获取锁，直接返回创建对象
        return singleton;
    }
}
